import axios from "axios"
import qs from "qs"
axios.defaults.baseURL = "api"
import { Message } from "element-ui"
import { Notification } from 'element-ui'
import { MessageBox } from "element-ui"
import router from "../router";
axios.timeout = 1000

axios.withCredentials = false





// 设置拦截器，以在每个请求中添加Token
axios.interceptors.request.use(
    (config) => {
        const token = localStorage.getItem('token'); // 假设你将token存储在本地存储中

        if (token) {
            // 如果存在token，则将token添加到请求头中
            config.headers['token'] = token;
        }
        removereqQueue(config) // 检查是否重复发送请求
        addreqQueue(config) //将本次请求加入请求队列
        return config
    },
    (error) => {
        console.log(error)
        Promise.reject(error)
    }
)

axios.interceptors.response.use(
    (res) => {
        removereqQueue(res.config) //请求从请求队列移除
        const data = res.data;
        if (data.retCode == 401) {
            localStorage.removeItem('token')
            MessageBox.alert('登录已过期,请重新登陆', {
                confirmButtonText: '确定',
                callback: () => {
                    // 跳转到登录页面
                    router.push('/login');

                }
            })
        }
        return res
    },
    (err) => {
        removereqQueue(err.config || {}) //请求从请求队列移除
        if (axios.isCancel(err)) {
            console.log('Request canceled', err.message)
            Message.error("服务器正在响应,请稍后~")
            return Promise.reject(err)
        }
        if (axios.isAxiosError(err)) {
            Message.error("服务器错误,请联系管理员~")
            return Promise.reject(err)
        }
        const res = err.response
        if (res.status == 404) {

            Notification.error({
                title: '404 not fount',
                dangerouslyUseHTMLString: true,
                message: '<strong>请求路径:</strong>' + res.data.path +
                    '<br/><strong>错误信息:</strong>' + err.message
            })
        }
    }
)

function regsoleKey(config) {
    const { method, url, params, data } = config
    return [method, url, qs.stringify(params), qs.stringify(data)].join("&")
}

const reqQueue = new Map()
function addreqQueue(config) {
    //调用生成唯一标识值函数, 生成 requestKey
    const requestKey = regsoleKey(config)
    //为每个请求创建一个专属的 CancelToken(用于取消请求)
    config.cancelToken =
        config.cancelToken ||
        new axios.CancelToken((cancel) => {
            // 判断 reqQueue 中是否含有 requestKey,
            // 将 requestKey 与 CancelToken 以键值对的形式保存到map对象中
            if (!reqQueue.has(requestKey)) {
                reqQueue.set(requestKey, cancel)
            }
        })
}

function removereqQueue(config) {
    // 标识值
    const requestKey = regsoleKey(config)

    if (reqQueue.has(requestKey)) {
        // 取消之前发出请求
        const cancelToken = reqQueue.get(requestKey)
        cancelToken(requestKey)
        // 从队列移除
        reqQueue.delete(requestKey)
    }
}

export default {
    get(url, data = {}, config = {}) {
        return new Promise((resolve, reject) => {
            axios
                .get(url, data, config)
                .then((response) => {
                    resolve(response)
                }).catch(err => { reject(err) })

        })
    },
    post(url, data = {}, config = {}) {
        return new Promise((resolve, reject) => {
            axios
                .post(url, data, config)
                .then((response) => {
                    resolve(response)
                })
                .catch((err) => {
                    reject(err)
                })
        })
    },
    delete(url, data = {}, config = {}) {
        return new Promise((resolve, reject) => {
            axios
                .delete(url, data, config)
                .then((response) => {
                    resolve(response)
                })
                .catch((err) => {
                    reject(err)
                })
        })
    },
    put(url, data = {}, config = {}) {
        return new Promise((resolve, reject) => {
            axios
                .put(url, data, config)
                .then((response) => {
                    resolve(response)
                })
                .catch((err) => {
                    reject(err)
                })
        })
    },
}